#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <string>

#include "TFile.h"
#include "TTree.h"
#include "TChain.h"
#include "TH1F.h"
#include "TH2F.h"
#include "TCanvas.h"
#include "TPad.h"
#include "TStyle.h"
#include "TROOT.h"
#include "TMath.h"

#include "CommandLineInterface.hh"
#include "Barrel.hh"
#include "Annular.hh"
#include "Germanium.hh"

using namespace TMath;
using namespace std;

ClassImp(Barrel);
ClassImp(Annular);
ClassImp(Germanium);

int main(int argc, char* argv[]){
  vector<char*> InputFiles;
  char* OutputFile = NULL;
  bool verbose = false;
  int all = 1;
  int tiltcorr = 0;
  CommandLineInterface* interface = new CommandLineInterface();

  interface->Add("-i", "inputfiles", &InputFiles);
  interface->Add("-o", "outputfile", &OutputFile);
  interface->Add("-a", "all histos? 0 only Erear vs Pos for each strip 2 no gammas and no cd", &all);
  interface->Add("-t", "1 tiltcorr histos, 0 no tiltcorr", &tiltcorr);
  interface->Add("-v", "verbose", &verbose);
  
  interface->CheckFlags(argc, argv);

  if(InputFiles.size() == 0 || OutputFile == NULL){
    cerr<<"You have to provide at least one input file and the output file!"<<endl;
    exit(1);
  }

  cout<<"input file(s):"<<endl;
  for(unsigned int i=0; i<InputFiles.size(); i++){
    cout<<InputFiles[i]<<endl;
  }
      
  /*
  if(OutputFile == NULL){
    std::string s;
    s+=InputFile;
    int LastDot = s.rfind('.');
    s.replace(LastDot,(s.length()-LastDot),"_hist.root");
    OutputFile = new char[s.length()];
    strcpy(OutputFile,s.c_str());

    //OutputFile = s.c_str();
  }
  */
  cout<<"output file: "<<OutputFile<< endl;

  TChain* tr;
  tr = new TChain("caltr");
  for(unsigned int i=0; i<InputFiles.size(); i++){
    tr->Add(InputFiles[i]);
  }

  if(tr == NULL){
    cout << "could not find tree caltr in file " << endl;
    for(unsigned int i=0; i<InputFiles.size(); i++){
      cout<<InputFiles[i]<<endl;
    }
    return 3;
  }

  vector<Barrel> *FBarrel = new vector<Barrel>;
  vector<Barrel> *BBarrel = new vector<Barrel>;
  vector<Annular> *BCD = new vector<Annular>;
  vector<Germanium> *Miniball = new vector<Germanium>;
  long long EbisTime;
  long long T1Time;
  long long SuperCycleTime;

  tr->SetBranchAddress("ForwardBarrel",&FBarrel);
  tr->SetBranchAddress("BackwardBarrel",&BBarrel);
  tr->SetBranchAddress("BackwardCD",&BCD);
  tr->SetBranchAddress("Miniball",&Miniball);
  tr->SetBranchAddress("EbisTime",&EbisTime);
  tr->SetBranchAddress("T1Time",&T1Time);
  tr->SetBranchAddress("SuperCycleTime",&SuperCycleTime);

  TFile* outfile = new TFile(OutputFile,"recreate");

  if(outfile->IsZombie()){
    return 4;
  }
  //barrel
  TH1F* ForwardBarrel_deltaE[4];
  TH1F* ForwardBarrel_Erest[4];
  TH1F* ForwardBarrel_Mult[4];
  TH2F* ForwardBarrel_StripEPos[2][4][16];
  TH2F* ForwardBarrel_EPos[4];
  TH2F* ForwardBarrel_dEvsStrip[4];
  TH2F* ForwardBarrel_ErestvsStrip[4];
  TH2F* ForwardBarrel_EvsStrip[4];
  TH2F* ForwardBarrel_PosvsStrip[4];
  TH2F* ForwardBarrel_DeltaEEall;
  TH2F* ForwardBarrel_DeltaEEcut;
  TH2F* ForwardBarrel_DeltaEEtot[4];
  TH2F* ForwardBarrel_DeltaEE[4][16];
  TH2F* ForwardBarrel_DeltaEErest[4][16];
  TH1F* ForwardBarrel_Pos[4][16];

  TH1F* ForwardBarrel_Erestcal[4][16][10];

  TH1F* BackwardBarrel_deltaE[4];
  TH1F* BackwardBarrel_Erest[4];
  TH1F* BackwardBarrel_Mult[4];
  TH2F* BackwardBarrel_StripEPos[2][4][16];
  TH2F* BackwardBarrel_EPos[4];
  TH2F* BackwardBarrel_dEvsStrip[4];
  TH2F* BackwardBarrel_ErestvsStrip[4];
  TH2F* BackwardBarrel_EvsStrip[4];
  TH2F* BackwardBarrel_PosvsStrip[4];
  TH2F* BackwardBarrel_DeltaEE[4];
  TH1F* BackwardBarrel_Pos[4][16];

  TH1F* BackwardBarrel_dEForStrip[4][16];
  TH1F* ForwardBarrel_dEForStrip[4][16];

  TH1F* ForwardBarrel_TEbis = new TH1F("ForwardBarrel_T_TEbis", "ForwardBarrel_T_TEbis", 3400, 0, 34000);
  TH1F* ForwardBarrel_T1 = new TH1F("ForwardBarrel_T_T1", "ForwardBarrel_T_T1", 1000, 0, 1e7);
  TH1F* ForwardBarrel_TSC = new TH1F("ForwardBarrel_T_TSC", "ForwardBarrel_T_TSC", 1000, 0, 1e7);
      ForwardBarrel_DeltaEEall = new TH2F(Form("ForwardBarrel_DeltaEEall"), Form("DeltaE vs E of all Forward Barrels"),100,0,20000,75,0,15000);
      ForwardBarrel_DeltaEEcut = new TH2F(Form("ForwardBarrel_DeltaEEcut"), Form("DeltaE vs E of all Forward Barrels cutted"),1000,0,20000,750,0,15000);

  for(int i=0;i<4;i++){
    ForwardBarrel_Mult[i] = new TH1F(Form("ForwardBarrel_Mult_%d",i),Form("multiplicity of Forward Barrel %d",i), 5, 0, 5);
    ForwardBarrel_deltaE[i] = new TH1F(Form("ForwardBarrel_deltaE_%d",i),Form("DeltaE of Forward Barrel %d",i), 500/2., 0, 10000);
    ForwardBarrel_Erest[i] = new TH1F(Form("ForwardBarrel_Erest_%d",i),Form("Erest of Forward Barrel %d",i), 500, 0, 10000);
    ForwardBarrel_EvsStrip[i] = new TH2F(Form("ForwardBarrel_EvsStrip_%d",i), Form("Energy vs Strip Nr of Forward Barrel %d",i),16,0,16,750,0,15000);
    ForwardBarrel_ErestvsStrip[i] = new TH2F(Form("ForwardBarrel_ErestvsStrip_%d",i), Form("Rest energy vs Strip Nr of Forward Barrel %d",i),16,0,16,750,0,15000);
    ForwardBarrel_dEvsStrip[i] = new TH2F(Form("ForwardBarrel_dEvsStrip_%d",i), Form("Rear vs Strip Nr of Forward Barrel %d",i),16,0,16,750,0,15000);
    //ForwardBarrel_PosvsStrip[i] = new TH2F(Form("ForwardBarrel_PosvsStrip_%d",i), Form("Position vs Strip Nr of Forward Barrel %d",i),16,0,16,200,0,2);
    ForwardBarrel_PosvsStrip[i] = new TH2F(Form("ForwardBarrel_PosvsStrip_%d",i), Form("Position vs Strip Nr of Forward Barrel %d",i),16,0,16,128,0,1.5);
      ForwardBarrel_DeltaEEtot[i] = new TH2F(Form("ForwardBarrel_DeltaEEtot_%d",i), Form("DeltaE vs E of Forward Barrel %d total",i),1000,0,20000,750,0,15000);
    BackwardBarrel_Mult[i] = new TH1F(Form("BackwardBarrel_Mult_%d",i),Form("multiplicity of Backward Barrel %d",i), 5, 0, 5);
    BackwardBarrel_deltaE[i] = new TH1F(Form("BackwardBarrel_deltaE_%d",i),Form("DeltaE of Backward Barrel %d",i), 500, 0, 10000);
    BackwardBarrel_Erest[i] = new TH1F(Form("BackwardBarrel_Erest_%d",i),Form("Erest of Backward Barrel %d",i), 500, 0, 10000);
    BackwardBarrel_EvsStrip[i] = new TH2F(Form("BackwardBarrel_EvsStrip_%d",i), Form("Energy vs Strip Nr of Backward Barrel %d",i),16,0,16,750,0,15000);
    BackwardBarrel_ErestvsStrip[i] = new TH2F(Form("BackwardBarrel_ErestvsStrip_%d",i), Form("Rest energy vs Strip Nr of Backward Barrel %d",i),16,0,16,750,0,15000);
    BackwardBarrel_dEvsStrip[i] = new TH2F(Form("BackwardBarrel_dEvsStrip_%d",i), Form("Rear vs Strip Nr of Backward Barrel %d",i),16,0,16,750,0,15000);
    BackwardBarrel_PosvsStrip[i] = new TH2F(Form("BackwardBarrel_PosvsStrip_%d",i), Form("Position vs Strip Nr of Backward Barrel %d",i),16,0,16,128,0,1.5);
    //BackwardBarrel_PosvsStrip[i] = new TH2F(Form("BackwardBarrel_PosvsStrip_%d",i), Form("Position vs Strip Nr of Backward Barrel %d",i),16,0,16,200,0,2);
    BackwardBarrel_DeltaEE[i] = new TH2F(Form("BackwardBarrel_DeltaEErest_%d",i), Form("DeltaE vs Erest of Backward Barrel %d",i),512,0,4096,750,0,15000);

    ForwardBarrel_EPos[i] = new TH2F(Form("ForwardBarrel_EPos_%d",i),Form("Energy vs Position of Forward Barrel %d",i), 200, 0, 2, 500, 0, 10000);
    BackwardBarrel_EPos[i] = new TH2F(Form("BackwardBarrel_EPos_%d",i),Form("Energy vs Position of Backward Barrel %d",i), 200, 0, 2, 500, 0, 10000);


    for(int j=0;j<16;j++){
      ForwardBarrel_DeltaEE[i][j] = new TH2F(Form("ForwardBarrel_DeltaEE_%d_%d",i,j), Form("DeltaE vs E of Forward Barrel %d Strip %d",i,j),1000,0,20000,750,0,15000);
      ForwardBarrel_DeltaEErest[i][j] = new TH2F(Form("ForwardBarrel_DeltaEErest_%d_%d",i,j), Form("DeltaE vs Erest of Forward Barrel %d Strip %d",i,j),1000,0,20000,750,0,15000);

      for(int k=0;k<2;k++){
	ForwardBarrel_StripEPos[k][i][j] = new TH2F(Form("ForwardBarrel_StripEPos_%dHits_%d_%d",k+1,i,j),Form("Energy vs Position of Strip %d of Forward Barrel %d for %d Hits",j,i,k+1), 200, 0, 2, 500, 0, 10000);
	
	BackwardBarrel_StripEPos[k][i][j] = new TH2F(Form("BackwardBarrel_StripEPos_%dHits_%d_%d",k+1,i,j),Form("Energy vs Position of Strip %d of Backward Barrel %d for %d Hits",j,i,k+1), 200, 0, 2, 500, 0, 10000);
      }
      BackwardBarrel_Pos[i][j] = new TH1F(Form("BackwardBarrel_Pos_%d_%d",i,j),Form("Position of Strip %d of Backward Barrel %d",j,i), 500, 0, 1.5);
      ForwardBarrel_Pos[i][j] = new TH1F(Form("ForwardBarrel_Pos_%d_%d",i,j),Form("Position of Strip %d of Forward Barrel %d",j,i), 500, 0, 1.5);

      BackwardBarrel_dEForStrip[i][j]  = new TH1F(Form("BackwardBarrel%d_dEForStrip_%d",i,j),Form("Backward Barrel %d energy hit in Strip %d",j,i), 500, 0, 10000);
      ForwardBarrel_dEForStrip[i][j]  = new TH1F(Form("ForwardBarrel%d_dEForStrip_%d",i,j),Form("Forward Barrel %d energy hit in Strip %d",j,i), 500, 0, 10000);

      for(int k=0;k<10;k++){
      ForwardBarrel_Erestcal[i][j][k] = new TH1F(Form("ForwardBarrel%d_Erestcal_%d_%d",i,j,k),Form("Erest %d strip %d for deltaE <%d && > %d",i,j,5000-400*k,5000-400*(k+1)),200,0,20000);
      }

    }
  }
  TH1F* FTiltCorr[4][16][10];
  TH1F* BTiltCorr[4][16][10];
  for(int i=0;i<4;i++){
    for(int k=0;k<16;k++){
      for(int j=0;j<10;j++){
	FTiltCorr[i][k][j] = new TH1F(Form("FBD%dStrip_%d_Posalong_%d",i,k,j), Form("FBD%dStrip_%d_Posalong_%d",i,k,j), 512,0,4096);
	BTiltCorr[i][k][j] = new TH1F(Form("BBD%dStrip_%d_Posalong_%d",i,k,j), Form("BBD%dStrip_%d_Posalong_%d",i,k,j), 512,0,4096);
      }
    }
  }

  TH2F* StripNr1vsNr2[4];
  TH2F* StripPos1vsPos2[4];
  for(int i=0;i<4;i++){
    StripNr1vsNr2[i] = new TH2F(Form("StripNr1vsNr2_%d",i),Form("StripNr1vsNr2_%d",i),16,0,16,16,0,16);
    StripPos1vsPos2[i] = new TH2F(Form("StripPos1vsPos2_%d",i),Form("StripPos1vsPos2_%d",i),200,0,2,200,0,2);
  }
  //cd
  TH2F* BackwardCD_dEvsStrip[4];
  TH2F* BackwardCD_dEvsRing[4];
  TH2F* BackwardCD_StripvsRing[4];
  TH2F* BackwardCD_dEvsE[4];
  TH1F* BackwardCD_E[4];
  TH2F* BackwardCD_1vs2_Strip[4];  
  TH2F* BackwardCD_1vs2_Ring[4];
  TH1F* BackwardCD_dEforStrip[4][16];
  TH1F* BackwardCD_dEforRing[4][16];

  for(int i=0;i<4;i++){
    BackwardCD_dEvsStrip[i] = new TH2F(Form("BackwardCD_dEvsStrip_%d",i), Form("deltaE vs Strip Nr of Backward CD %d",i),16,0,16,750,0,15000);
    BackwardCD_dEvsRing[i] = new TH2F(Form("BackwardCD_dEvsRing_%d",i), Form("deltaE vs Ring Nr of Backward CD %d",i),16,0,16,750,0,15000);
    BackwardCD_StripvsRing[i] = new TH2F(Form("BackwardCD_StripvsRing_%d",i), Form("Strip vs Ring Energy of Backward CD %d",i),750,0,15000,750,0,15000);
    BackwardCD_dEvsE[i] = new TH2F(Form("BackwardCD_dEvsE_%d",i), Form("deltaE vs Erest of Backward CD %d",i),512,0,4096,750,0,15000);
    BackwardCD_E[i] = new TH1F(Form("BackwardCD_E_%d",i), Form("Erest of Backward CD %d",i),1024,0,4096);  
    BackwardCD_1vs2_Ring[i] = new TH2F(Form("BackwardCD_1vs2_Ring_%d",i), Form("first nr vs second nr Ring of Backward CD %d",i),16,0,16,16,0,16);  
    BackwardCD_1vs2_Strip[i] = new TH2F(Form("BackwardCD_1vs2_Strip_%d",i), Form("first nr vs second nr Strip of Backward CD %d",i),16,0,16,16,0,16);  
    for(int j=0;j<16;j++){
      BackwardCD_dEforStrip[i][j] = new TH1F(Form("BackwardCD_dEforStrip_%d_%d",i,j), Form("BackwardCD_dEforStrip_%d_%d",i,j), 2000,0,7000);
      BackwardCD_dEforRing[i][j] = new TH1F(Form("BackwardCD_dEforRing_%d_%d",i,j), Form("BackwardCD_dEforRing_%d_%d",i,j), 2000,0,7000);
    }
  } 
  
  //gamma
  TH1F* EGamS[8][3][6];
  TH1F* EGamC[8][3];
  TH1F* TGamC[8][3];
  TH1F* EGamCall;
  TH1F* EGamCcut;

  TH2F* EGamCEGamC[8];
  TH2F* EGamCbigTdiff[8];
  TH2F* EGamCsmallTdiff[8];

  TH2F* EGamCpartTdiff[4];
  TH2F* EGamCpartTdiffall;

  EGamCall = new TH1F(Form("EGamCall"),Form("EGamCall"),400, 0, 4000);	
  EGamCcut = new TH1F(Form("EGamCcut"),Form("EGamCcut"),400, 0, 4000);	

  for(int i=0;i<8;i++){ // cluster
    for(int k=0;k<3;k++){ // crystal
      for(int j=0;j<6;j++){ // segment

	EGamS[i][k][j] = new TH1F(Form("EGamCl%dCr%dSe%d",i,k,j),Form("EGamCl%dCr%dSe%d",i,k,j),400, 0, 4000);
      }
      EGamC[i][k] = new TH1F(Form("EGamCl%dCr%d",i,k),Form("EGamCl%dCr%d",i,k),400, 0, 4000);	
      TGamC[i][k] = new TH1F(Form("TGamCl%dCr%d",i,k),Form("TGamCl%dCr%d",i,k),1000, 0, 340000);
    }
    EGamCEGamC[i] = new TH2F(Form("EGamCEGamC%d",i),Form("EGamCEGamC%d",i),500, 0, 4000,500, 0, 4000); 
    EGamCbigTdiff[i] = new TH2F(Form("EGamCbigTdiff%d",i),Form("EGamCbigTdiff%d",i),40, -20, 20,500, 0, 4000);
    EGamCsmallTdiff[i] = new TH2F(Form("EGamCsmallTdiff%d",i),Form("EGamCsmallTdiff%d",i),40, -20, 20,500, 0, 4000);
  }
  for(int k=0;k<4;k++){ // barrel quadrant
    EGamCpartTdiff[k] = new TH2F(Form("EGamCpartTdiff%d",k),Form("EGamCpartTdiff%d",k),40, -40, 40,500, 0, 4000);
  }
    EGamCpartTdiffall = new TH2F(Form("EGamCpartTdiffall"),Form("EGamCpartTdiffall"),40, -500, 500,200, 0, 2000);

// END HISTOGRAMS

bool partfound;
  double time[4];
  Double_t nentries = tr->GetEntries();
  Int_t nbytes = 0;
  Int_t status;
  for(int i=0; i<nentries;i++){
    status = tr->GetEvent(i);
    if(status == -1){
      cerr<<"Error occured, couldn't read entry "<<i<<" from tree "<<tr->GetName()<<" in file "<<tr->GetFile()->GetName()<<endl;
      return 5;
    }
    else if(status == 0){
      cerr<<"Error occured, entry "<<i<<" in tree "<<tr->GetName()<<" in file "<<tr->GetFile()->GetName()<<" doesn't exist"<<endl;
      return 6;
    }
    nbytes += status;

    partfound =false;
    for(int k=0;k<4;k++)
      time[k]=0.;

    //forward barrel
    for(unsigned int j=0; j<FBarrel->size(); j++){
      if((*FBarrel)[j].GetMult() ==0)
      	continue;

      if( (*FBarrel)[j].GetID() < 0 || (*FBarrel)[j].GetID() > 3 ){
	cerr<<"Error in entry "<<i<<": "<<j<<". forward barrel detector id is wrong: "<<(*FBarrel)[j].GetID()<<endl;	
	continue;
      }

      if( (*FBarrel)[j].GetStripNr()[0] < 0 || (*FBarrel)[j].GetStripNr()[0] > 15 ){
	cerr<<"Error in entry "<<i<<": "<<(*FBarrel)[j].GetID()<<". forward barrel detector strip nr is wrong: "<<(*FBarrel)[j].GetStripNr()[0]<<endl;	
	continue;
      }
      /*
      if((*FBarrel)[j].GetStripNr().size()!=2)
	continue;
      if((*FBarrel)[j].GetNeighbor())
      	continue;
      */
      partfound=true;
      time[(*FBarrel)[j].GetID()] = (*FBarrel)[j].GetTime();

      if((*FBarrel)[j].GetStripNr().size()==2){
	StripNr1vsNr2[(*FBarrel)[j].GetID()]->Fill((*FBarrel)[j].GetStripNr()[0],(*FBarrel)[j].GetStripNr()[1]);
	StripPos1vsPos2[(*FBarrel)[j].GetID()]->Fill((*FBarrel)[j].GetStripPos()[0],(*FBarrel)[j].GetStripPos()[1]);
      }

      ForwardBarrel_TEbis->Fill((*FBarrel)[j].GetTime()-EbisTime);
      ForwardBarrel_T1->Fill((*FBarrel)[j].GetTime()-T1Time);
      ForwardBarrel_TSC->Fill((*FBarrel)[j].GetTime()-SuperCycleTime);
      //cout << "p - ebis " << (*FBarrel)[j].GetTime() -  EbisTime << endl;
      //filling histos
      if(all!=0){
	
	ForwardBarrel_deltaE[(*FBarrel)[j].GetID()]->Fill((*FBarrel)[j].GetRear());
	ForwardBarrel_Erest[(*FBarrel)[j].GetID()]->Fill((*FBarrel)[j].GetEdet());
	ForwardBarrel_EPos[(*FBarrel)[j].GetID()]->Fill((*FBarrel)[j].GetStripPos()[0],(*FBarrel)[j].GetRear());
	//(*FBarrel)[j].GetStripNr()[0] first hit
	ForwardBarrel_dEvsStrip[(*FBarrel)[j].GetID()]->Fill((*FBarrel)[j].GetStripNr()[0],(*FBarrel)[j].GetRear());
	ForwardBarrel_EvsStrip[(*FBarrel)[j].GetID()]->Fill((*FBarrel)[j].GetStripNr()[0],(*FBarrel)[j].GetRear()+(*FBarrel)[j].GetEdet());
	ForwardBarrel_ErestvsStrip[(*FBarrel)[j].GetID()]->Fill((*FBarrel)[j].GetStripNr()[0],(*FBarrel)[j].GetEdet());
	ForwardBarrel_PosvsStrip[(*FBarrel)[j].GetID()]->Fill((*FBarrel)[j].GetStripNr()[0],(*FBarrel)[j].GetStripPos()[0]);
	ForwardBarrel_DeltaEEtot[(*FBarrel)[j].GetID()]->Fill((*FBarrel)[j].GetEdet(), (*FBarrel)[j].GetRear());
	ForwardBarrel_DeltaEEall->Fill((*FBarrel)[j].GetEdet(), (*FBarrel)[j].GetRear());
	ForwardBarrel_DeltaEE[(*FBarrel)[j].GetID()][(*FBarrel)[j].GetStripNr()[0]]->Fill((*FBarrel)[j].GetRear()+(*FBarrel)[j].GetEdet(), (*FBarrel)[j].GetRear());
	ForwardBarrel_DeltaEErest[(*FBarrel)[j].GetID()][(*FBarrel)[j].GetStripNr()[0]]->Fill((*FBarrel)[j].GetEdet(), (*FBarrel)[j].GetRear());
	
	ForwardBarrel_Mult[(*FBarrel)[j].GetID()]->Fill((*FBarrel)[j].GetMult());
	ForwardBarrel_Pos[(*FBarrel)[j].GetID()][(*FBarrel)[j].GetStripNr()[0]]->Fill((*FBarrel)[j].GetStripPos()[0]);


	  if(((8.5e6/((*FBarrel)[j].GetEdet()+4e3))<(*FBarrel)[j].GetRear())&&(1.4e8/((*FBarrel)[j].GetEdet()+1.2e4)>(*FBarrel)[j].GetRear()))
	  {
		ForwardBarrel_DeltaEEcut->Fill((*FBarrel)[j].GetEdet(), (*FBarrel)[j].GetRear());
      for(unsigned int jG=0; jG<Miniball->size(); jG++){
			for(unsigned int kG=0; kG<(*Miniball)[j].GetCrystal().size();kG++){  
				EGamCcut->Fill((*Miniball)[jG].GetCrystal()[kG].GetCore());
	  		}
		}
	  }


	if((*FBarrel)[j].GetEdet()>100){
	  for(int m=0;m<10;m++){
	    if((*FBarrel)[j].GetRear()<5000-400*m  && (*FBarrel)[j].GetRear()>5000-400*(m+1) )
	      ForwardBarrel_Erestcal[(*FBarrel)[j].GetID()][(*FBarrel)[j].GetStripNr()[0]][m]->Fill((*FBarrel)[j].GetEdet());
	  }
	}
      }
      
      //cout << "entry "<<i<<" Filling Forward" << (*FBarrel)[j].GetID() << " Strip " << (*FBarrel)[j].GetStripNr()[0] << " with energy " << (*FBarrel)[j].GetRear() << endl;
      ForwardBarrel_dEForStrip[(*FBarrel)[j].GetID()][(*FBarrel)[j].GetStripNr()[0]]->Fill((*FBarrel)[j].GetRear());
      for(unsigned int k=0;k<(*FBarrel)[j].GetStripNr().size();k++){
	ForwardBarrel_StripEPos[k][(*FBarrel)[j].GetID()][(*FBarrel)[j].GetStripNr()[k]]->Fill((*FBarrel)[j].GetStripPos()[k],(*FBarrel)[j].GetRear());
      }
      //special histos for tilt correction
      if((*FBarrel)[j].GetMult()==1){
	if(tiltcorr==1){
	  for(int k=0;k<10;k++){
	    if( ((*FBarrel)[j].GetStripPos()[0]>=k/10.) && ((*FBarrel)[j].GetStripPos()[0]<(k+1)/10.) ){
	      FTiltCorr[(*FBarrel)[j].GetID()][(*FBarrel)[j].GetStripNr()[0]][k]->Fill((*FBarrel)[j].GetRear());
	    }
	  }
	}
      }

    }
    
    //end forward barrel
    //backward barrel
    for(unsigned int j=0; j<BBarrel->size(); j++){
      if((*BBarrel)[j].GetMult() ==0)
      	continue;
      if( (*BBarrel)[j].GetID() < 0 || (*BBarrel)[j].GetID() > 3 ){
	cerr<<"Error in entry "<<i<<": "<<j<<". backward barrel detector id is wrong: "<<(*BBarrel)[j].GetID()<<endl;	
	continue;
      }
      if( (*BBarrel)[j].GetStripNr()[0] < 0 || (*BBarrel)[j].GetStripNr()[0] > 15 ){
	cerr<<"Error in entry "<<i<<": "<<j<<". backward barrel detector strip nr is wrong: "<<(*BBarrel)[j].GetStripNr()[0]<<endl;	
	continue;
      }
      //filling histos
      if(all!=0){      
	BackwardBarrel_deltaE[(*BBarrel)[j].GetID()]->Fill((*BBarrel)[j].GetRear());
	BackwardBarrel_Erest[(*BBarrel)[j].GetID()]->Fill((*BBarrel)[j].GetEdet());
	BackwardBarrel_EPos[(*BBarrel)[j].GetID()]->Fill((*BBarrel)[j].GetStripPos()[0],(*BBarrel)[j].GetRear());
	//(*BBarrel)[j].GetStripNr()[0] first hit
	
	BackwardBarrel_dEvsStrip[(*BBarrel)[j].GetID()]->Fill((*BBarrel)[j].GetStripNr()[0],(*BBarrel)[j].GetRear());
	BackwardBarrel_EvsStrip[(*BBarrel)[j].GetID()]->Fill((*BBarrel)[j].GetStripNr()[0],(*BBarrel)[j].GetRear()+(*BBarrel)[j].GetEdet());
	BackwardBarrel_ErestvsStrip[(*BBarrel)[j].GetID()]->Fill((*BBarrel)[j].GetStripNr()[0],(*BBarrel)[j].GetEdet());
	BackwardBarrel_PosvsStrip[(*BBarrel)[j].GetID()]->Fill((*BBarrel)[j].GetStripNr()[0],(*BBarrel)[j].GetStripPos()[0]);
	BackwardBarrel_DeltaEE[(*BBarrel)[j].GetID()]->Fill((*BBarrel)[j].GetEdet(), (*BBarrel)[j].GetRear());
	
	BackwardBarrel_Mult[(*BBarrel)[j].GetID()]->Fill((*BBarrel)[j].GetMult());
	BackwardBarrel_Pos[(*BBarrel)[j].GetID()][(*BBarrel)[j].GetStripNr()[0]]->Fill((*BBarrel)[j].GetStripPos()[0]);
      }
      for(unsigned int k=0;k<(*BBarrel)[j].GetStripNr().size();k++){
	BackwardBarrel_StripEPos[k][(*BBarrel)[j].GetID()][(*BBarrel)[j].GetStripNr()[k]]->Fill((*BBarrel)[j].GetStripPos()[k],(*BBarrel)[j].GetRear());
      }

      //cout << "entry "<<i<<" Filling Backward" << (*BBarrel)[j].GetID() << " Strip " << (*BBarrel)[j].GetStripNr()[0] << " with energy " << (*BBarrel)[j].GetRear() << endl;
      
      BackwardBarrel_dEForStrip[(*BBarrel)[j].GetID()][(*BBarrel)[j].GetStripNr()[0]]->Fill((*BBarrel)[j].GetRear());

      //special histos for tilt correction
      if(tiltcorr==1){
	for(int k=0;k<10;k++){
	  if( ((*BBarrel)[j].GetStripPos()[0]>=k/10.) && ((*BBarrel)[j].GetStripPos()[0]<(k+1)/10.) ){
	    BTiltCorr[(*BBarrel)[j].GetID()][(*BBarrel)[j].GetStripNr()[0]][k]->Fill((*BBarrel)[j].GetRear());
	  }
	}
      }

    }
    
    //end backward barrel

    //backward cd
    if(all==1){
      for(unsigned int j=0; j<BCD->size(); j++){
	if( (*BCD)[j].GetID() < 0 || (*BCD)[j].GetID() >= 4 ){
	  cerr<<"Error in entry "<<i<<": "<<j<<". backward barrel detector id is wrong: "<<(*BCD)[j].GetID()<<endl;	
	  continue;
	}
	
	//filling histos
	if((*BCD)[j].GetRingNr().size() == 2){
	  BackwardCD_1vs2_Ring[(*BCD)[j].GetID()]->Fill( (*BCD)[j].GetRingNr()[1], (*BCD)[j].GetRingNr()[0] );
	}
	if((*BCD)[j].GetStripNr().size() == 2){
	  BackwardCD_1vs2_Strip[(*BCD)[j].GetID()]->Fill( (*BCD)[j].GetStripNr()[1], (*BCD)[j].GetStripNr()[0] );
	}
	
	for( unsigned int k=0;k<(*BCD)[j].GetRingNr().size();k++){
	  if(verbose)
	    cout << "ring nr " << (*BCD)[j].GetRingNr()[k] << " with energy " << (*BCD)[j].GetRingEnergy()[k] << endl;
	  BackwardCD_dEvsRing[(*BCD)[j].GetID()]->Fill( (*BCD)[j].GetRingNr()[k], (*BCD)[j].GetRingEnergy()[k] );
	  BackwardCD_dEforRing[(*BCD)[j].GetID()][(*BCD)[j].GetRingNr()[k]]->Fill((*BCD)[j].GetRingEnergy()[k]);
	}
	for(unsigned int k=0;k<(*BCD)[j].GetStripNr().size();k++){
	  if(verbose)
	    cout << "strip nr " << (*BCD)[j].GetStripNr()[k] << " with energy " << (*BCD)[j].GetStripEnergy()[k] << endl;
	  BackwardCD_dEvsStrip[(*BCD)[j].GetID()]->Fill( (*BCD)[j].GetStripNr()[k], (*BCD)[j].GetStripEnergy()[k] );
	  BackwardCD_dEforStrip[(*BCD)[j].GetID()][(*BCD)[j].GetStripNr()[k]]->Fill((*BCD)[j].GetStripEnergy()[k]);
	}
	if( (*BCD)[j].GetStripNr().size() == 1 && (*BCD)[j].GetRingNr().size() == 1 ){
	  BackwardCD_StripvsRing[(*BCD)[j].GetID()]->Fill( (*BCD)[j].GetRingEnergy()[0], (*BCD)[j].GetStripEnergy()[0] );
	}
	BackwardCD_dEvsE[(*BCD)[j].GetID()]->Fill( (*BCD)[j].GetEdet(), (*BCD)[j].GetRingEnergy()[0] );
	BackwardCD_E[(*BCD)[j].GetID()]->Fill( (*BCD)[j].GetEdet());
      }
    }
    //end backward cd
    //gammas
    if(all!=2){
      for(unsigned int j=0; j<Miniball->size(); j++){
	if((*Miniball)[j].GetCluID()<0 || (*Miniball)[j].GetCluID()>7){
	  cout << "Error in entry "<<i<<": "<<j<<". Germanium detector Cluster id is wrong: "<<(*Miniball)[j].GetCluID()<<endl;	
	  continue;
	}
	//cout << "(*Miniball)[j].GetCrystal().size() " << (*Miniball)[j].GetCrystal().size() << endl;
	for(unsigned int k=0; k<(*Miniball)[j].GetCrystal().size();k++){  
	  if( (*Miniball)[j].GetCrystal()[k].GetCryID() <0 || (*Miniball)[j].GetCrystal()[k].GetCryID() >2){
	    cout << "Error in entry "<<i<<": "<<j<<". Germanium detector Crystal id is wrong: "<<(*Miniball)[j].GetCrystal()[k].GetCryID()<<endl;	
	    continue;
	  }
	

	  EGamCall->Fill((*Miniball)[j].GetCrystal()[k].GetCore());
	  EGamC[(*Miniball)[j].GetCluID()][(*Miniball)[j].GetCrystal()[k].GetCryID()]->Fill((*Miniball)[j].GetCrystal()[k].GetCore());
	  TGamC[(*Miniball)[j].GetCluID()][(*Miniball)[j].GetCrystal()[k].GetCryID()]->Fill((*Miniball)[j].GetCrystal()[k].GetTime()-EbisTime);
	  for(unsigned int l=0;l<(*Miniball)[j].GetCrystal()[k].GetSegID().size();l++){
	    if(verbose)
	      cout << "filling cluster " <<(*Miniball)[j].GetCluID() << " crystal " << (*Miniball)[j].GetCrystal()[k].GetCryID() << " segment " << (*Miniball)[j].GetCrystal()[k].GetSegID()[l] << endl; 
	    EGamS[(*Miniball)[j].GetCluID()][(*Miniball)[j].GetCrystal()[k].GetCryID()][(*Miniball)[j].GetCrystal()[k].GetSegID()[l]]->Fill((*Miniball)[j].GetCrystal()[k].GetSeg()[l]);
	  }
	}
	if((*Miniball)[j].GetCrystal().size()==2 ){
	  if(verbose)
	    cout << "2 hits in cluster " << (*Miniball)[j].GetCluID() << endl;
	  if( (*Miniball)[j].GetCrystal()[0].GetCore()>50 && (*Miniball)[j].GetCrystal()[1].GetCore()>50 ){ // only events with two energies
	    if((*Miniball)[j].GetCrystal()[0].GetCore() > (*Miniball)[j].GetCrystal()[1].GetCore()){
	      EGamCEGamC[(*Miniball)[j].GetCluID()]->Fill((*Miniball)[j].GetCrystal()[0].GetCore(), (*Miniball)[j].GetCrystal()[1].GetCore());
	      EGamCbigTdiff[(*Miniball)[j].GetCluID()]->Fill((*Miniball)[j].GetCrystal()[0].GetTime()-(*Miniball)[j].GetCrystal()[1].GetTime(), (*Miniball)[j].GetCrystal()[0].GetCore());
	      EGamCsmallTdiff[(*Miniball)[j].GetCluID()]->Fill((*Miniball)[j].GetCrystal()[0].GetTime()-(*Miniball)[j].GetCrystal()[1].GetTime(), (*Miniball)[j].GetCrystal()[1].GetCore());
	    }
	    else{ //1 > 0
	      EGamCEGamC[(*Miniball)[j].GetCluID()]->Fill((*Miniball)[j].GetCrystal()[1].GetCore(), (*Miniball)[j].GetCrystal()[0].GetCore());
	      EGamCbigTdiff[(*Miniball)[j].GetCluID()]->Fill((*Miniball)[j].GetCrystal()[1].GetTime()-(*Miniball)[j].GetCrystal()[0].GetTime(), (*Miniball)[j].GetCrystal()[1].GetCore());
	      EGamCsmallTdiff[(*Miniball)[j].GetCluID()]->Fill((*Miniball)[j].GetCrystal()[1].GetTime()-(*Miniball)[j].GetCrystal()[0].GetTime(), (*Miniball)[j].GetCrystal()[0].GetCore());

	    }
	  }
	}
	if(partfound){
	  for(int k=0;k<4;k++){
	    if(time[k]>0)
	      EGamCpartTdiff[k]->Fill((*Miniball)[j].GetCrystal()[0].GetTime()-time[k], (*Miniball)[j].GetCrystal()[0].GetCore());
	      EGamCpartTdiffall->Fill(((*Miniball)[j].GetCrystal()[0].GetTime()-time[k])*25, (*Miniball)[j].GetCrystal()[0].GetCore());
	  }
	}
      }//end gammas
    }
    if(i%1000 == 0){
      cout<<setw(5)<<setiosflags(ios::fixed)<<setprecision(1)<<(100.*i)/nentries<<" % done\r"<<flush;
    }
    
  }//nr of entries

    // barrel
  if(all!=0){
    for(int i=0;i<4;i++){
      ForwardBarrel_Mult[i]->Write("",TObject::kOverwrite);
      ForwardBarrel_deltaE[i]->Write("",TObject::kOverwrite);
      ForwardBarrel_Erest[i]->Write("",TObject::kOverwrite);
      ForwardBarrel_EvsStrip[i]->Write("",TObject::kOverwrite);
      ForwardBarrel_ErestvsStrip[i]->Write("",TObject::kOverwrite);
      ForwardBarrel_dEvsStrip[i]->Write("",TObject::kOverwrite);
      ForwardBarrel_PosvsStrip[i]->Write("",TObject::kOverwrite);
		ForwardBarrel_DeltaEEtot[i]->Write("",TObject::kOverwrite);
      
      BackwardBarrel_Mult[i]->Write("",TObject::kOverwrite);
      BackwardBarrel_deltaE[i]->Write("",TObject::kOverwrite);
      BackwardBarrel_Erest[i]->Write("",TObject::kOverwrite);
      BackwardBarrel_EvsStrip[i]->Write("",TObject::kOverwrite);
      BackwardBarrel_ErestvsStrip[i]->Write("",TObject::kOverwrite);
      BackwardBarrel_dEvsStrip[i]->Write("",TObject::kOverwrite);
      BackwardBarrel_PosvsStrip[i]->Write("",TObject::kOverwrite);
      BackwardBarrel_DeltaEE[i]->Write("",TObject::kOverwrite);
      ForwardBarrel_EPos[i]->Write("",TObject::kOverwrite);
      BackwardBarrel_EPos[i]->Write("",TObject::kOverwrite);
      for(int j=0;j<16;j++){
	ForwardBarrel_Pos[i][j]->Write("",TObject::kOverwrite);
	ForwardBarrel_DeltaEE[i][j]->Write("",TObject::kOverwrite);
	ForwardBarrel_DeltaEErest[i][j]->Write("",TObject::kOverwrite);
	BackwardBarrel_Pos[i][j]->Write("",TObject::kOverwrite);
      }    
    }
    
    // cd
    for(int i=0;i<4;i++){
      BackwardCD_dEvsRing[i]->Write("",TObject::kOverwrite);
      BackwardCD_dEvsStrip[i]->Write("",TObject::kOverwrite);
      BackwardCD_StripvsRing[i]->Write("",TObject::kOverwrite);
      BackwardCD_dEvsE[i]->Write("",TObject::kOverwrite);
      BackwardCD_E[i]->Write("",TObject::kOverwrite);
      BackwardCD_1vs2_Ring[i]->Write("",TObject::kOverwrite);
      BackwardCD_1vs2_Strip[i]->Write("",TObject::kOverwrite);
      for(int j=0;j<16;j++){
	BackwardCD_dEforStrip[i][j]->Write("",TObject::kOverwrite);
	BackwardCD_dEforRing[i][j]->Write("",TObject::kOverwrite);
      }
    }
    
  }
  for(int i=0;i<4;i++){
    for(int j=0;j<16;j++){
      for(int k=0;k<2;k++){
	ForwardBarrel_StripEPos[k][i][j]->Write("",TObject::kOverwrite);
	BackwardBarrel_StripEPos[k][i][j]->Write("",TObject::kOverwrite);
      }
      ForwardBarrel_dEForStrip[i][j]->Write("",TObject::kOverwrite);
      BackwardBarrel_dEForStrip[i][j]->Write("",TObject::kOverwrite);
      for(int k=0;k<10;k++){
      	ForwardBarrel_Erestcal[i][j][k]->Write("",TObject::kOverwrite);
      }

    }
  }
  if(tiltcorr==1){
    for(int i=0;i<4;i++){
      for(int k=0;k<16;k++){
	for(int j=0;j<10;j++){
	  FTiltCorr[i][k][j]->Write("",TObject::kOverwrite);
	  BTiltCorr[i][k][j]->Write("",TObject::kOverwrite);
	}
      }
    }
  }
  if(all!=2){
		EGamCcut->Write("",TObject::kOverwrite);
		EGamCall->Write("",TObject::kOverwrite);
    for(int i=0;i<8;i++){ // cluster
      for(int k=0;k<3;k++){ // crystal
	for(int j=0;j<6;j++){ // segment
	  EGamS[i][k][j]->Write("",TObject::kOverwrite);
	}
	EGamC[i][k]->Write("",TObject::kOverwrite);
	TGamC[i][k]->Write("",TObject::kOverwrite);
      }
      EGamCEGamC[i]->Write("",TObject::kOverwrite);
      EGamCbigTdiff[i]->Write("",TObject::kOverwrite);
      EGamCsmallTdiff[i]->Write("",TObject::kOverwrite);
    }
    for(int k=0;k<4;k++) // quadrant      
      EGamCpartTdiff[k]->Write("",TObject::kOverwrite);
  }
  EGamCpartTdiffall->Write("",TObject::kOverwrite);

  ForwardBarrel_TEbis->Write("",TObject::kOverwrite);
  ForwardBarrel_T1->Write("",TObject::kOverwrite);
  ForwardBarrel_TSC->Write("",TObject::kOverwrite);
  ForwardBarrel_DeltaEEall->Write("",TObject::kOverwrite);
  ForwardBarrel_DeltaEEcut->Write("",TObject::kOverwrite);

  for(int i=0;i<4;i++){ 
    StripNr1vsNr2[i]->Write("",TObject::kOverwrite);
    StripPos1vsPos2[i]->Write("",TObject::kOverwrite);
  }
  outfile->Close();
  delete tr;

  return 0;

}
